﻿using System.ComponentModel;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using AntDesign;
using Blazor.Core.Extensions;
using Blazor.Localization;
using Blazor.Pages;
using Blazor.Views.UpdateSetting;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using ReactiveUI;
using ReactiveUI.Blazor;

namespace Blazor.Core;

public abstract class SoraniComponentBase<T>: ReactiveComponentBase<T>, ISoraniComponent
    where T : class, INotifyPropertyChanged
{
    protected readonly CompositeDisposable Disposables = [];
    
    [Inject]
    public IStringLocalizer<CommonLocalization> CommonLoc { get; set; }
    
    [Inject]
    public MessageService MessageService { get; set; }

    [Inject]
    public ModalService ModalService { get; set; }

    public SoraniComponentBase()
    {
        this.WhenActivated(disposable =>
        {
            this.WhenAnyValue(x => x.ViewModel)
                .WhereNotNull()
                .Select(vm => Observable.Defer(() =>
                    {
                        var d = new CompositeDisposable();
                        BindWithViewModel(vm, d);
                        return Observable.Return(vm)
                            .Concat(Observable.Never<T>())
                            .Finally(() => d.Dispose()); // 显式释放资源
                    }
                ))
                .Switch()
                .Publish()
                .RefCount()
                .Subscribe()
                .DisposeWith(disposable);
        });
    }

    protected abstract void BindWithViewModel(T viewModel, CompositeDisposable disposable);
    
    public void ShowOperateFailedMessage()
    {
        MessageService.Error(CommonLoc[CommonLocalization.Failed].ToString());
    }
    
    public void ShowOperateSuccessfullyMessage()
    {
        MessageService.Success(CommonLoc[CommonLocalization.Success].ToString());
    }

    public Task<TResult?> OpenCustomModal<TModal, TParam, TResult>(TParam param) where TModal : FeedbackComponent<TParam, TResult>
    {
        return ModalService.OpenCustomModal<TModal, TParam, TResult>(param);
    }

    public Task<bool> WhenConfirm(string content)
    {
        return ModalService.WhenConfirm(CommonLoc[CommonLocalization.Tip], content);
    }

    public Task<bool> WhenConfirm(string content, string title)
    {
        return ModalService.WhenConfirm(title, content);
    }

    protected override void Dispose(bool disposing)
    {
        Disposables.Dispose();
        base.Dispose(disposing);
    }
}